#include "LCD1602.h"

/*******************************************
函数名称：LCDSetPosition
输入参数：x-列，y-行 x:0-15 y:0-1
输出参数：无
函数功能：设置显示位置   DDRAM地址
*********************************************/
void LCDSetPosition(unsigned char x, unsigned char y)
{
	if(0 == y)
	{
		LCDWriteCmd(0x80 | x);
	}
	else if (1 == y)
	{
		LCDWriteCmd(0x80 | (0x40 + x));
	}	
}

/*******************************************
函数名称：LCDReadBF
输入参数：无
输出参数：无
函数功能：1602读忙检测
*********************************************/
void LCDReadBF()
{
	unsigned char state;
	unsigned char i;
	LCD1602_DB = 0xFF;//IO置1 做输入
	LCD1602_RS = 0;
	LCD1602_RW = 1;
	do
	{
		LCD1602_EN = 1;
		state = LCD1602_DB;
		LCD1602_EN = 0;
		i++;
		if(i > 50)
			break;
	}
	while(state & 0x80);
}

/*******************************************
函数名称：LCDWriteCmd
输入参数：cmd 待写命令
输出参数：无
函数功能：LCD1602写命令
*********************************************/
void LCDWriteCmd(unsigned char cmd)
{
	LCDReadBF();//等待忙检测。不忙时操作
	LCD1602_RS = 0;
	LCD1602_RW = 0;
	LCD1602_DB = cmd;
	LCD1602_EN = 1;
	LCD1602_EN = 0;
}

/*******************************************
函数名称：LCDWriteData
输入参数：dat 待写数据
输出参数：无
函数功能：LCD1602写数据
*********************************************/
void LCDWriteData(unsigned char dat)
{
	LCDReadBF();//等待忙检测。不忙时操作
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DB = dat;
	LCD1602_EN = 1;
	LCD1602_EN = 0;
}

/*******************************************
函数名称：LCDInit
输入参数：无
输出参数：无
函数功能：LCD1602初始化
*********************************************/
void LCDInit()
{
	LCDWriteCmd(LCD_MODE_PIN8);//显示模式设置 2行 5*8点阵
	LCDWriteCmd(LCD_DIS_ON);//显示开 光标关
	LCDWriteCmd(LCD_CURSOR_RIGHT);//光标右移
	LCDWriteCmd(LCD_SCREEN_CLR);//清屏
}

/*******************************************
函数名称：LCDShowStr
输入参数：x-列，y-行  *str-待显示字符数据
输出参数：无
函数功能：显示字符
*********************************************/
void LCDShowStr(unsigned char x, unsigned char y,unsigned char *str)
{
	LCDSetPosition(x, y);
	while(*str != '\0')
	{
		LCDWriteData(*str++);
	}
}

/*******************************************
函数名称：LCDWriteCGRAM
输入参数：*str-自定义字符数据
输出参数：无
函数功能：显示自定义字符
*********************************************/
void LCDWriteCGRAM(unsigned char *str)
{
	unsigned char i;
	LCDWriteCmd(LCD_SET_CGRAM_ADDR);//1、构造自定义字符
	for (i = 0; i < 8; i++)
	{
		LCDWriteData(*str++); //写入自定义字符
	}
	//显示这个字符
	LCDWriteCmd(0x80 | 0x00);//设定屏幕上的显示位置
	LCDWriteData(0x00);		 //从 CGRAM 里取出自定义字符显示
}

/*******************************************
函数名称：LCDSetChar
输入参数：x-列，y-行  pos-CGRAM位置 *str-自定义字符数据
输出参数：无
函数功能：显示自定义字符
*********************************************/
void LCDSetChar(unsigned char x, unsigned char y, unsigned char pos, unsigned char *str)
{
	unsigned char i;
	//先构造自定义字符 确定位置 CGRAM
	for (i = 0;i < 8; i++)
	{
		LCDWriteCmd(LCD_SET_CGRAM_ADDR + pos * 8 + i);
		LCDWriteData(*(str+i));
	}
	//显示
	LCDSetPosition(x,y);//设置显示位置 DDRAM
	LCDWriteData(0x00 + pos);//显示代码位置
}

unsigned char IntegerToStr(int dat, unsigned char *str)
{
	unsigned char i;//数据的索引
	unsigned char len = 0;//数据长度的返回
	unsigned char buf[6];//存放字符串
	if (dat < 0)
	{
		dat = -dat;//如果是负数，取绝对值
		*str++ = '-';
		len++;
	}
	do
	{
		buf[i++] = dat % 10 + '0';//dat % 10 + 0x30
		dat /= 10;
	}while(dat > 0);
	len += i;
	while(i-- > 0)
	{
		*str++ = buf[i];
	}
	*str = '\0';
	return len;
}
